package com.hpf.tool.utils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;

/**
 * 字符串工具类
 * @author houbinfei
 *
 */
public final class UtilsString {
	/**
	 * 首字母转换为大写
	 * <pre>first = First</pre>
	 * @param str 要转换的字符串
	 * @return
	 */
	public static String firstToUpperCase(String str) {
		if(isEmpty(str)){ return "";}
		return str.substring(0, 1).toUpperCase() + str.substring(1, str.length());
	}

	/**
	 * 首字母转换为小写
	 * <pre>First = first</pre>
	 * @param str 要转换的字符串
	 * @return
	 */
	public static String firstToLowerCase(String str) {
		if(isEmpty(str)){ return "";}
		return str.substring(0, 1).toLowerCase() + str.substring(1, str.length());
	}
	
	public static void main(String[] args) {
		System.out.println(UtilsString.firstToLowerCase(""));
	}
	/**
	 * 转换为驼峰命名形式,首字母是否大写
	 * <pre>first_to_lower_case = firstToLowerCas</pre>
	 * @param str要转换的字符串
	 * @param flag 首字母是否大写，true 大写、false 小写
	 * @return
	 */
	public static String toHump(String str, boolean flag) {
		String[] list = str.toLowerCase().split("_");
		// 说明可以截取
		if (list.length > 1) {
			StringBuffer sb = new StringBuffer();
			for (String val : list) {
				sb.append(firstToUpperCase(val));
			}
			str = sb.toString();
			sb = null;
		}
		// flag = true 转大写 or flag = false 转小写
		return flag ? firstToUpperCase(str) : firstToLowerCase(str);
	}


	/**
	 * <p>验证对象是否为 empty</p>
	 * <pre>
	 * UtilsString.isEmpty(null)            = true
	 * UtilsString.isEmpty(0)               = true
	 * UtilsString.isEmpty("")              = true
	 * UtilsString.isEmpty(" ")             = true
	 * UtilsString.isEmpty(" test ")        = false
	 * UtilsString.isEmpty(Collection)      = true
	 * UtilsString.isEmpty(Map)             = true
	 * UtilsString.isEmpty(Set)             = true
	 * </pre>
	 * @param obj 
	 * @return
	 */
	public static <T> boolean isEmpty(T t) {
		if (null == t) {
			return true;
		}
		
		// t extends Integer
		if (t instanceof Number && ((Number)t).doubleValue() == 0) {
			return true;
		}
				
		// t extends CharSequence
		if (t instanceof CharSequence && "".equals(t.toString().trim())) {
			return true;
		}
		
		// t extends Collection
		if (t instanceof Collection && ((Collection<?>)t).isEmpty()) {
			return true;
		}
		// Map
		if (t instanceof Map && ((Map<?, ?>) t).isEmpty()) {
			return true;
		}
		// Set
		if (t instanceof Set && ((Set<?>) t).isEmpty()) {
			return true;
		}
		return false;
	}
	
	/**
	 * <p>验证对象不为 empty</p>
	 * <pre>
	 * UtilsString.isNotEmpty(null)			= false
	 * UtilsString.isNotEmpty(0)			= false
	 * UtilsString.isNotEmpty("")			= false
	 * UtilsString.isNotEmpty(" ")			= false
	 * UtilsString.isNotEmpty(" test ")		= true
	 * UtilsString.isNotEmpty(Collection)   = false
	 * UtilsString.isNotEmpty(Map)			= false
	 * UtilsString.isNotEmpty(Set)			= false
	 * </pre>
	 * @param obj
	 * @return
	 */
	public static <T> boolean isNotEmpty(T t) {
		return UtilsString.isEmpty(t) ? false : true;
	}
	
	/**
	 * 字符串截取
	 * @param value
	 * @param size 截取长度
	 * @return
	 */
	public static String substring(String value, int size) {
		if(isEmpty(value)){
			return "";
		}
		if(value.length() <= size){
			return value;
		}
		return value.substring(0, size);
	}
	
	/**
	 * 校验数据 是否全部为空
	 * </br>描述：只要有一个数据为空 => false，否则 => true
	 * @param data
	 * @return
	 */
	public static boolean allEmpty(Map<String, Object> data){
		if(isEmpty(data)){
			return true;
		}
		for (Map.Entry<String, Object> entry : data.entrySet()) {
			if(isEmpty(entry) == true){
				// 只要有一个不为 Empty ,则表示不全为 空
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 校验数据 是否全部为空
	 * </br>描述：只要有一个数据为空 => false，否则 => true
	 * @param data
	 * @return
	 */
	public static boolean allEmpty(Object ... list){
		if(null == list || list.length <= 0){
			return true;
		}
		for (Object item : list) {
			if(isEmpty(item) == true){
				// 只要有一个不为 Empty ,则表示不全为 空
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 验证一个数字是否为奇数
	 * @param num
	 * @return
	 */
	public static boolean isOdd(int num){
		return num % 2== 1;
	}
	
	/**
	 * 解析时间
	 * @param target 目标字符串
	 * @param format 格式化字符串
	 * @return
	 */
	public static Date parseDate(String target, String format){
		if(isEmpty(target)){
			throw new RuntimeException("目标字符串为空");
		}
		if(isEmpty(format)){
			format = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat df = new SimpleDateFormat(format);
		try {
			return df.parse(target);
		} catch (Exception ex) {
			throw new RuntimeException("解析时间异常",ex);
		}
	}
	
	/**
	 * 格式化时间
	 * @param target 目标字符串
	 * @param format 格式化字符串
	 * @return
	 */
	public static String formatDate(Date target, String format){
		if(target == null){
			target = new Date();
		}
		if(isEmpty(format)){
			format = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat df = new SimpleDateFormat(format);
		try {
			return df.format(target);
		} catch (Exception ex) {
			throw new RuntimeException("格式化时间异常",ex);
		}
	}
	
	/**
	 * 格式化时间
	 * @param format 格式化字符串
	 * @return
	 */
	public static String formatDate(String format){
		return formatDate(null,format);
	}
	
	/**
	 * 格式化时间
	 * @param target 目标字符串
	 * @return
	 */
	public static String formatDate(Date target){
		return formatDate(target,null);
	}
	
	/**
	 * 解析时间
	 * @param target 目标字符串
	 * @param format 格式化字符串
	 * @return
	 */
	public static Date parseDate(String target){
		return parseDate(target,null);
	}

	/**
	 * 集合是否包含目标字符串
	 * @param collection 集合字符串
	 * @param target 目标字符串
	 * @return
	 */
	public static boolean includes(String[] collection, String target){
		if(isEmpty(collection)) {
			throw new RuntimeException("collection is empty");
		}
		for (String str:collection) {
			if(str.equals(target)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 验证集合是否包含某个元素
	 * @param collection 接
	 * @param fn 验证方法
	 * @param <T> 目标集合
	 * @return
	 */
	public static <T> boolean includes(List<T> collection, Function<T,Boolean> fn){
		if(isEmpty(collection)) {
			throw new RuntimeException("collection is empty");
		}
		if (fn == null) {
			throw new RuntimeException("Function is null");
		}
		for (T t:collection) {
			boolean result = fn.apply(t);
			if(result) {
				return true;
			}else {
				continue;
			}
		}
		return false;
	}

	/**
	 * 截取为字符串数组
	 * @param target 目标字符串
	 * @param separatrix 截取符
	 * @return
	 */
	public static String[] splitArray(String target, String separatrix){
		if(isEmpty(target)) {
			throw new RuntimeException("target is empty");
		}
		if(isEmpty(separatrix)) {
			throw new RuntimeException("separatrix is empty");
		}
		try {
			return target.split(separatrix);
		}catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	/**
	 * 截取为 List<String>
	 * @param target 目标字符串
	 * @param separatrix 截取符
	 * @return
	 */
	public static List<String> splitList(String target, String separatrix){
		String[] resultString = splitArray(target,separatrix);
		if (isEmpty(resultString)) {
			throw new RuntimeException("result is empty");
		}
		List<String> resultList = new ArrayList<String>(resultString.length);
		for (String item: resultString) {
			resultList.add(item);
		}
		return resultList;
	}
}
